It is possible to extend file locking by making it mandatory on all processes, whether or not they were designed to be part of the cooperating group. Mandatory locking, as defined under "Mandatory Locking", is enforced by the file I/O function calls. As a result, an independent process that calls write() to update a locked record will be blocked. The write() function tests for a contending lock internally. Of course, the same test is made by write() when called by a cooperating process, in which case it represents unnecessary overhead.
Mandatory locking is enforced on a file-by-file basis, triggered by a bit in the file inode that is set by chmod (see the chmod(1) and chmod(2) reference pages). In order to enforce mandatory locking on a particular file, turn on the set-group-ID bit along with a nonexecutable group permission ("2644" permissions, for example). This must be done before the file is opened; a change has no effect on a file that is already open.
Example 4-8 shows a fragment of code that sets mandatory lock mode on a given filename.
Example 4-8 : Setting Mandatory Locking Permission Bits
#include <sys/types.h> #include <sys/stat.h> int setMandatoryLocking(char *filename) { int mode; struct stat buf; if (stat(filename, &buf) < 0) { perror("stat(2)"); return error; } mode = buf.st_mode; /* ensure group execute permission 0010 bit is off */ mode &= ~(S_IEXEC>>3); /* turn on 'set group id bit' in mode */ mode |= S_ISGID; if (chmod(filename, mode) < 0) { perror("chmod(2)"); return error; } return 0; }When IRIX opens a file, it checks to see whether both of two conditions are true:
Some points to remember about mandatory locking: